home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Applications / P4⁄Mac 2.0d4 / Mac source 2.0 / pcode.p < prev    next >
Encoding:
Text File  |  1996-09-28  |  37.9 KB  |  1,836 lines  |  [TEXT/PJMM]

  1. (*Assembler and interpreter of Pascal code*)
  2. (*K. Jensen, N. Wirth, Ch. Jacobi, ETH May 76*)
  3.  
  4. {Mac port by Ingemar Ragnemalm 1994-1996. Look for "{” comments to find my changes.}
  5.  
  6. unit pcode;
  7. {(input, output, prd, prr);}
  8. interface
  9.     uses
  10. {$IFC UNDEFINED THINK_PASCAL}
  11.         Types, QuickDraw, Windows, Dialogs, ToolUtils, Events, Controls, {}
  12.         Memory, Sound, OSUtils, MixedMode, 
  13. {$ENDC}
  14.         NewOldFile, Messages, Console;
  15.  
  16.     procedure InitInterpreter;
  17.     procedure RunInterpreter (oldFile: Str255);
  18.  
  19. implementation
  20.  
  21.  
  22. (* Note for the implementation.}
  23. {   ===========================}
  24. {This interpreter is written for the case where all the fundamental types}
  25. {take one storage unit.}
  26. {In an actual implementation, the handling of the sp pointer has to take}
  27. {into account the fact that the types may have lengths different from one:}
  28. {in push and pop operations the sp has to be increased and decreased not}
  29. {by 1, but by a number depending on the type concerned.}
  30. {However, where the number of units of storage has been computed by the}
  31. {compiler, the value must not be corrected, since the lengths of the types}
  32. {involved have already been taken into account.}
  33. {                                 *)
  34.  
  35.     procedure InitInterpreter;
  36.     begin
  37.     end;
  38.  
  39.  
  40.  
  41.     const
  42.         codemax = 8650;
  43.         pcmax = 17500;
  44.         maxstk = 13650; (* size of variable store *)
  45.         overi = 13655; (* size of integer constant table = 5 *)
  46.         overr = 13660; (* size of real constant table = 5 *)
  47.         overs = 13730; (* size of set constant table = 70 *)
  48.         overb = 13820;
  49.         overm = 18000;
  50.         maxstr = 18001;
  51.         largeint = 26144;
  52.         begincode = 3;
  53.         inputadr = 5;
  54.         outputadr = 6;
  55.         prdadr = 7;
  56.         prradr = 8;
  57.         duminst = 62;
  58.  
  59.     type
  60.         bit4 = 0..15;
  61.         bit6 = 0..127;
  62.         bit20 = -26143..26143;
  63.         datatype = (undef, int, reel, bool, sett, adr, mark, car);
  64.         address = -1..maxstr;
  65.         beta = string[25]; {IR: Was: packed array[1..25] of char;}
  66.  (*error message*)
  67.         settype = set of 0..58;
  68.         alfa = packed array[1..10] of char;
  69.  
  70.         codeType = array[0..codemax] of packed record   (* the program *)
  71.                 op1: bit6;
  72.                 p1: bit4;
  73.                 q1: bit20;
  74.                 op2: bit6;
  75.                 p2: bit4;
  76.                 q2: bit20
  77.             end;
  78.         codePtr = ^codeType;
  79.  
  80.         storeType = array[0..overm] of record
  81.                 case datatype of
  82.                     int: (
  83.                             vi: integer
  84.                     );
  85.                     reel: (
  86.                             vr: real
  87.                     );
  88.                     bool: (
  89.                             vb: boolean
  90.                     );
  91.                     sett: (
  92.                             vs: settype
  93.                     );
  94.                     car: (
  95.                             vc: char
  96.                     );
  97.                     adr: (
  98.                             va: address
  99.                     );
  100.                          (*address in store*)
  101.                     mark: (
  102.                             vm: integer
  103.                     )
  104.             end;
  105.         storePtr = ^storeType;
  106.  
  107.     var
  108.         code: codePtr;
  109.  
  110.         pc: 0..pcmax;     (*program address register*)
  111.         op: bit6;
  112.         p: bit4;
  113.         q: bit20;  (*instruction register*)
  114.  
  115.         store: storePtr;
  116.  
  117. {Ovanstående variabler är utanför för att store och code skall vara statiska.}
  118.  
  119.     procedure RunInterpreter (oldFile: Str255);
  120.  
  121.         var
  122.             mp, sp, np, ep: address;  (* address registers *)
  123.        (*mp  points to beginning of a data segment}
  124. {     sp  points to top of the stack}
  125. {     ep  points to the maximum extent of the stack}
  126. {     np  points to top of the dynamically allocated area*)
  127.  
  128.             interpreting: boolean;
  129.             prd, prr: text;(*prd for read only, prr for write only *)
  130.  
  131.             instr: array[bit6] of alfa; (* mnemonic instruction codes *)
  132.             cop: array[bit6] of integer;
  133.             sptable: array[0..20] of alfa; (*standard functions and procedures*)
  134.  
  135.       (*locally used for interpreting one instruction*)
  136.             ad, ad1: address;
  137.             b: boolean;
  138.             i, j, i1, i2: integer;
  139.             c: char;
  140.  
  141.         label
  142.             1;
  143.  
  144. (*--------------------------------------------------------------------*)
  145.  
  146.         procedure load;
  147.             const
  148.                 maxlabel = 1850;
  149.             type
  150.                 labelst = (entered, defined); (*label situation*)
  151.                 labelrg = 0..maxlabel;       (*label range*)
  152.                 labelrec = record
  153.                         val: address;
  154.                         st: labelst
  155.                     end;
  156.             var
  157.                 icp, rcp, scp, bcp, mcp: address;  (*pointers to next free position*)
  158.                 word: array[1..10] of char;
  159.                 i: integer;
  160.                 ch: char;
  161.                 labeltab: array[labelrg] of labelrec;
  162.                 labelvalue: address;
  163.  
  164.             procedure init;
  165.                 var
  166.                     i: integer;
  167.             begin
  168.                 instr[0] := 'lod       ';
  169.                 instr[1] := 'ldo       ';
  170.                 instr[2] := 'str       ';
  171.                 instr[3] := 'sro       ';
  172.                 instr[4] := 'lda       ';
  173.                 instr[5] := 'lao       ';
  174.                 instr[6] := 'sto       ';
  175.                 instr[7] := 'ldc       ';
  176.                 instr[8] := '...       ';
  177.                 instr[9] := 'ind       ';
  178.                 instr[10] := 'inc       ';
  179.                 instr[11] := 'mst       ';
  180.                 instr[12] := 'cup       ';
  181.                 instr[13] := 'ent       ';
  182.                 instr[14] := 'ret       ';
  183.                 instr[15] := 'csp       ';
  184.                 instr[16] := 'ixa       ';
  185.                 instr[17] := 'equ       ';
  186.                 instr[18] := 'neq       ';
  187.                 instr[19] := 'geq       ';
  188.                 instr[20] := 'grt       ';
  189.                 instr[21] := 'leq       ';
  190.                 instr[22] := 'les       ';
  191.                 instr[23] := 'ujp       ';
  192.                 instr[24] := 'fjp       ';
  193.                 instr[25] := 'xjp       ';
  194.                 instr[26] := 'chk       ';
  195.                 instr[27] := 'eof       ';
  196.                 instr[28] := 'adi       ';
  197.                 instr[29] := 'adr       ';
  198.                 instr[30] := 'sbi       ';
  199.                 instr[31] := 'sbr       ';
  200.                 instr[32] := 'sgs       ';
  201.                 instr[33] := 'flt       ';
  202.                 instr[34] := 'flo       ';
  203.                 instr[35] := 'trc       ';
  204.                 instr[36] := 'ngi       ';
  205.                 instr[37] := 'ngr       ';
  206.                 instr[38] := 'sqi       ';
  207.                 instr[39] := 'sqr       ';
  208.                 instr[40] := 'abi       ';
  209.                 instr[41] := 'abr       ';
  210.                 instr[42] := 'not       ';
  211.                 instr[43] := 'and       ';
  212.                 instr[44] := 'ior       ';
  213.                 instr[45] := 'dif       ';
  214.                 instr[46] := 'int       ';
  215.                 instr[47] := 'uni       ';
  216.                 instr[48] := 'inn       ';
  217.                 instr[49] := 'mod       ';
  218.                 instr[50] := 'odd       ';
  219.                 instr[51] := 'mpi       ';
  220.                 instr[52] := 'mpr       ';
  221.                 instr[53] := 'dvi       ';
  222.                 instr[54] := 'dvr       ';
  223.                 instr[55] := 'mov       ';
  224.                 instr[56] := 'lca       ';
  225.                 instr[57] := 'dec       ';
  226.                 instr[58] := 'stp       ';
  227.                 instr[59] := 'ord       ';
  228.                 instr[60] := 'chr       ';
  229.                 instr[61] := 'ujc       ';
  230.  
  231.                 sptable[0] := 'get       ';
  232.                 sptable[1] := 'put       ';
  233.                 sptable[2] := 'rst       ';
  234.                 sptable[3] := 'rln       ';
  235.                 sptable[4] := 'new       ';
  236.                 sptable[5] := 'wln       ';
  237.                 sptable[6] := 'wrs       ';
  238.                 sptable[7] := 'eln       ';
  239.                 sptable[8] := 'wri       ';
  240.                 sptable[9] := 'wrr       ';
  241.                 sptable[10] := 'wrc       ';
  242.                 sptable[11] := 'rdi       ';
  243.                 sptable[12] := 'rdr       ';
  244.                 sptable[13] := 'rdc       ';
  245.                 sptable[14] := 'sin       ';
  246.                 sptable[15] := 'cos       ';
  247.                 sptable[16] := 'exp       ';
  248.                 sptable[17] := 'log       ';
  249.                 sptable[18] := 'sqt       ';
  250.                 sptable[19] := 'atn       ';
  251.                 sptable[20] := 'sav       ';
  252.  
  253.                 cop[0] := 105;
  254.                 cop[1] := 65;
  255.                 cop[2] := 70;
  256.                 cop[3] := 75;
  257.                 cop[6] := 80;
  258.                 cop[9] := 85;
  259.                 cop[10] := 90;
  260.                 cop[26] := 95;
  261.                 cop[57] := 100;
  262.  
  263.                 pc := begincode;
  264.                 icp := maxstk + 1;
  265.                 rcp := overi + 1;
  266.                 scp := overr + 1;
  267.                 bcp := overs + 2;
  268.                 mcp := overb + 1;
  269.                 for i := 1 to 10 do
  270.                     word[i] := ' ';
  271.                 for i := 0 to maxlabel do
  272.                     with labeltab[i] do
  273.                         begin
  274.                             val := -1;
  275.                             st := entered
  276.                         end;
  277.                 reset(prd);
  278.             end;(*init*)
  279.  
  280.             procedure errorl (theString: beta); (*error in loading*)
  281.             begin
  282.                 WriteLnMessage;                    {was writeln}
  283.                 WriteMessage(theString);        {was write}
  284.                 Exit(RunInterpreter);             {was halt}
  285.             end; (*errorl*)
  286.  
  287.             procedure update (x: labelrg); (*when a label definition lx is found*)
  288.                 var
  289.                     curr, succ: -1..pcmax;  (*resp. current element and successor element}
  290. {                   of a list of future references*)
  291.                     endlist: boolean;
  292.             begin
  293.                 if labeltab[x].st = defined then
  294.                     errorl(' duplicated label           ')
  295.                 else
  296.                     begin
  297.                         if labeltab[x].val <> -1 then (*forward reference(s)*)
  298.                             begin
  299.                                 curr := labeltab[x].val;
  300.                                 endlist := false;
  301.                                 while not endlist do
  302.                                     with code^[curr div 2] do
  303.                                         begin
  304.                                             if odd(curr) then
  305.                                                 begin
  306.                                                     succ := q2;
  307.                                                     q2 := labelvalue
  308.                                                 end
  309.                                             else
  310.                                                 begin
  311.                                                     succ := q1;
  312.                                                     q1 := labelvalue
  313.                                                 end;
  314.                                             if succ = -1 then
  315.                                                 endlist := true
  316.                                             else
  317.                                                 curr := succ
  318.                                         end;
  319.                             end;
  320.                         labeltab[x].st := defined;
  321.                         labeltab[x].val := labelvalue;
  322.                     end
  323.             end;(*update*)
  324.  
  325.             procedure assemble;
  326.             forward;
  327.  
  328.             procedure generate;(*generate segment of code*)
  329.                 var
  330.                     x: integer; (* label number *)
  331.                     again: boolean;
  332.             begin
  333.                 again := true;
  334.                 while again do
  335.                     begin
  336.                         read(prd, ch);(* first character of line*)
  337.                         case ch of
  338.                             'i': 
  339.                                 readln(prd);
  340.                             'l': 
  341.                                 begin
  342.                                     read(prd, x);
  343.                                     if not eoln(prd) then
  344.                                         read(prd, ch);
  345.                                     if ch = '=' then
  346.                                         read(prd, labelvalue)
  347.                                     else
  348.                                         labelvalue := pc;
  349.                                     update(x);
  350.                                     readln(prd);
  351.                                 end;
  352.                             'q': 
  353.                                 begin
  354.                                     again := false;
  355.                                     readln(prd)
  356.                                 end;
  357.                             ' ': 
  358.                                 begin
  359.                                     read(prd, ch);
  360.                                     assemble
  361.                                 end
  362.                         end;
  363.                     end
  364.             end; (*generate*)
  365.  
  366.             procedure assemble; (*translate symbolic code into machine code and store*)
  367.                 label
  368.                     1;     (*goto 1 for instructions without code generation*)
  369.                 var
  370.                     name: alfa;
  371.                     b: boolean;
  372.                     r: real;
  373.                     s: settype;
  374.                     c1: char;
  375.                     i, s1, lb, ub: integer;
  376.  
  377.                 procedure lookup (x: labelrg); (* search in label table*)
  378.                 begin
  379.                     case labeltab[x].st of
  380.                         entered: 
  381.                             begin
  382.                                 q := labeltab[x].val;
  383.                                 labeltab[x].val := pc
  384.                             end;
  385.                         defined: 
  386.                             q := labeltab[x].val
  387.                     end(*case label..*)
  388.                 end;(*lookup*)
  389.  
  390.                 procedure labelsearch;
  391.                     var
  392.                         x: labelrg;
  393.                 begin
  394.                     while (ch <> 'l') and not eoln(prd) do
  395.                         read(prd, ch);
  396.                     read(prd, x);
  397.                     lookup(x)
  398.                 end;(*labelsearch*)
  399.  
  400.                 procedure getname;
  401.                     var
  402.                         i: integer; {fix for pack}
  403.                 begin
  404.                     word[1] := ch;
  405.                     read(prd, word[2], word[3]);
  406.                     if not eoln(prd) then
  407.                         read(prd, ch); (*next character*)
  408. {pack(word, 1, name) doesn't exist, replace by:}
  409.                     for i := 1 to 10 do {pack}
  410.                         name[i] := word[i]; {pack}
  411.                 end; (*getname*)
  412.  
  413.                 procedure typesymbol;
  414.                     var
  415.                         i: integer;
  416.                 begin
  417.                     if ch <> 'i' then
  418.                         begin
  419.                             case ch of
  420.                                 'a': 
  421.                                     i := 0;
  422.                                 'r': 
  423.                                     i := 1;
  424.                                 's': 
  425.                                     i := 2;
  426.                                 'b': 
  427.                                     i := 3;
  428.                                 'c': 
  429.                                     i := 4;
  430.                             end;
  431.                             op := cop[op] + i;
  432.                         end;
  433.                 end; (*typesymbol*)
  434.  
  435.             begin
  436.                 p := 0;
  437.                 q := 0;
  438.                 op := 0;
  439.                 getname;
  440.                 instr[duminst] := name;
  441.                 while instr[op] <> name do
  442.                     op := op + 1;
  443.                 if op = duminst then
  444.                     errorl(' illegal instruction     ');
  445.  
  446.                 case op of  (* get parameters p,q *)
  447.  
  448.       (*equ,neq,geq,grt,leq,les*)
  449.                     17, 18, 19, 20, 21, 22: 
  450.                         begin
  451.                             case ch of
  452.                                 'a': 
  453.                                     ; (*p = 0*)
  454.                                 'i': 
  455.                                     p := 1;
  456.                                 'r': 
  457.                                     p := 2;
  458.                                 'b': 
  459.                                     p := 3;
  460.                                 's': 
  461.                                     p := 4;
  462.                                 'c': 
  463.                                     p := 6;
  464.                                 'm': 
  465.                                     begin
  466.                                         p := 5;
  467.                                         read(prd, q)
  468.                                     end
  469.                             end
  470.                         end;
  471.  
  472.       (*lod,str*)
  473.                     0, 2: 
  474.                         begin
  475.                             typesymbol;
  476.                             read(prd, p, q)
  477.                         end;
  478.  
  479. 4  (*lda*)
  480.                     : 
  481.                         read(prd, p, q);
  482.  
  483. 12 (*cup*)
  484.                     : 
  485.                         begin
  486.                             read(prd, p);
  487.                             labelsearch
  488.                         end;
  489.  
  490. 11 (*mst*)
  491.                     : 
  492.                         read(prd, p);
  493.  
  494. 14 (*ret*)
  495.                     : 
  496.                         case ch of
  497.                             'p': 
  498.                                 p := 0;
  499.                             'i': 
  500.                                 p := 1;
  501.                             'r': 
  502.                                 p := 2;
  503.                             'c': 
  504.                                 p := 3;
  505.                             'b': 
  506.                                 p := 4;
  507.                             'a': 
  508.                                 p := 5
  509.                         end;
  510.  
  511.       (*lao,ixa,mov*)
  512.                     5, 16, 55: 
  513.                         read(prd, q);
  514.  
  515.       (*ldo,sro,ind,inc,dec*)
  516.                     1, 3, 9, 10, 57: 
  517.                         begin
  518.                             typesymbol;
  519.                             read(prd, q)
  520.                         end;
  521.  
  522.       (*ujp,fjp,xjp*)
  523.                     23, 24, 25: 
  524.                         labelsearch;
  525.  
  526. 13 (*ent*)
  527.                     : 
  528.                         begin
  529.                             read(prd, p);
  530.                             labelsearch
  531.                         end;
  532.  
  533. 15 (*csp*)
  534.                     : 
  535.                         begin
  536.                             for i := 1 to 9 do
  537.                                 read(prd, ch);
  538.                             getname;
  539.                             while name <> sptable[q] do
  540.                                 q := q + 1
  541.                         end;
  542.  
  543. 7 (*ldc*)
  544.                     : 
  545.                         begin
  546.                             case ch of  (*get q*)
  547.                                 'i': 
  548.                                     begin
  549.                                         p := 1;
  550.                                         read(prd, i);
  551.                                         if abs(i) >= largeint then
  552.                                             begin
  553.                                                 op := 8;
  554.                                                 store^[icp].vi := i;
  555.                                                 q := maxstk;
  556.                                                 repeat
  557.                                                     q := q + 1
  558.                                                 until store^[q].vi = i;
  559.                                                 if q = icp then
  560.                                                     begin
  561.                                                         icp := icp + 1;
  562.                                                         if icp = overi then
  563.                                                             errorl(' integer table overflow  ');
  564.                                                     end
  565.                                             end
  566.                                         else
  567.                                             q := i
  568.                                     end;
  569.  
  570.                                 'r': 
  571.                                     begin
  572.                                         op := 8;
  573.                                         p := 2;
  574.                                         read(prd, r);
  575.                                         store^[rcp].vr := r;
  576.                                         q := overi;
  577.                                         repeat
  578.                                             q := q + 1
  579.                                         until store^[q].vr = r;
  580.                                         if q = rcp then
  581.                                             begin
  582.                                                 rcp := rcp + 1;
  583.                                                 if rcp = overr then
  584.                                                     errorl(' real table overflow     ');
  585.                                             end
  586.                                     end;
  587.  
  588.                                 'n': 
  589.                                     ; (*p,q = 0*)
  590.  
  591.                                 'b': 
  592.                                     begin
  593.                                         p := 3;
  594.                                         read(prd, q)
  595.                                     end;
  596.  
  597.                                 'c': 
  598.                                     begin
  599.                                         p := 6;
  600.                                         repeat
  601.                                             read(prd, ch);
  602.                                         until ch <> ' ';
  603.                                         if ch <> '''' then
  604.                                             errorl(' illegal character       ');
  605.                                         read(prd, ch);
  606.                                         q := ord(ch);
  607.                                         read(prd, ch);
  608.                                         if ch <> '''' then
  609.                                             errorl(' illegal character       ');
  610.                                     end;
  611.                                 '(': 
  612.                                     begin
  613.                                         op := 8;
  614.                                         p := 4;
  615.                                         s := [];
  616.                                         read(prd, ch);
  617.                                         while ch <> ')' do
  618.                                             begin
  619.                                                 read(prd, s1, ch);
  620.                                                 s := s + [s1]
  621.                                             end;
  622.                                         store^[scp].vs := s;
  623.                                         q := overr;
  624.                                         repeat
  625.                                             q := q + 1
  626.                                         until store^[q].vs = s;
  627.                                         if q = scp then
  628.                                             begin
  629.                                                 scp := scp + 1;
  630.                                                 if scp = overs then
  631.                                                     errorl(' set table overflow      ');
  632.                                             end
  633.                                     end
  634.                             end (*case*)
  635.                         end;
  636.  
  637. 26 (*chk*)
  638.                     : 
  639.                         begin
  640.                             typesymbol;
  641.                             read(prd, lb, ub);
  642.                             if op = 95 then
  643.                                 q := lb
  644.                             else
  645.                                 begin
  646.                                     store^[bcp - 1].vi := lb;
  647.                                     store^[bcp].vi := ub;
  648.                                     q := overs;
  649.                                     repeat
  650.                                         q := q + 2
  651.                                     until (store^[q - 1].vi = lb) and (store^[q].vi = ub);
  652.                                     if q = bcp then
  653.                                         begin
  654.                                             bcp := bcp + 2;
  655.                                             if bcp = overb then
  656.                                                 errorl(' boundary table overflow ');
  657.                                         end
  658.                                 end
  659.                         end;
  660.  
  661. 56 (*lca*)
  662.                     : 
  663.                         begin
  664.                             if mcp + 16 >= overm then
  665.                                 errorl(' multiple table overflow ');
  666.                             mcp := mcp + 16;
  667.                             q := mcp;
  668.                             for i := 0 to 15 do (*stringlgth*)
  669.                                 begin
  670.                                     read(prd, ch);
  671.                                     store^[q + i].vc := ch
  672.                                 end;
  673.                         end;
  674.  
  675. 6 (*sto*)
  676.                     : 
  677.                         typesymbol;
  678.  
  679.                     27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 58: 
  680.                         ;
  681.  
  682.       (*ord,chr*)
  683.                     59, 60: 
  684.                         goto 1;
  685.  
  686. 61 (*ujc*)
  687.                     : 
  688.                         ; (*must have same length as ujp*)
  689.  
  690.                 end; (*case*)
  691.  
  692.       (* store instruction *)
  693.                 with code^[pc div 2] do
  694.                     if odd(pc) then
  695.                         begin
  696.                             op2 := op;
  697.                             p2 := p;
  698.                             q2 := q
  699.                         end
  700.                     else
  701.                         begin
  702.                             op1 := op;
  703.                             p1 := p;
  704.                             q1 := q
  705.                         end;
  706.                 pc := pc + 1;
  707. 1:
  708.                 readln(prd);
  709.             end; (*assemble*)
  710.  
  711.         begin (*load*)
  712.             init;
  713.             generate;
  714.             pc := 0;
  715.             generate;
  716.         end; (*load*)
  717.  
  718. (*------------------------------------------------------------------------*)
  719.  
  720.         procedure pmd;
  721.             var
  722.                 s: integer;
  723.                 i: integer;
  724.  
  725.             procedure pt;
  726.             begin
  727.                 ConsoleWrite(StringOf(s : 6));
  728.                 if abs(store^[s].vi) < maxint then
  729.                     ConsoleWrite(StringOf(store^[s].vi))
  730.                 else
  731.                     ConsoleWrite('too big ');
  732.                 s := s - 1;
  733.                 i := i + 1;
  734.                 if i = 4 then
  735.                     begin
  736.                         ConsoleNewLine;            {writeln(output);}
  737.                         i := 0
  738.                     end;
  739.             end; (*pt*)
  740.  
  741.         begin
  742.             ConsoleWrite(StringOf(' pc =', pc - 1 : 5, ' op =', op : 3, '  sp =', sp : 5, '  mp =', mp : 5, '  np =', np : 5));
  743.             ConsoleNewLine;
  744.             ConsoleWriteLn('--------------------------------------');
  745.  
  746.             s := sp;
  747.             i := 0;
  748.             while s >= 0 do
  749.                 pt;
  750.             s := maxstk;
  751.             while s >= np do
  752.                 pt;
  753.         end; (*pmd*)
  754.  
  755.         procedure errori (theString: beta);
  756.         begin
  757.             ConsoleNewLine;
  758.             ConsoleWriteLn(theString);
  759.             pmd;
  760.             goto 1
  761.         end;(*errori*)
  762.  
  763.         function base (ld: integer): address;
  764.             var
  765.                 ad: address;
  766.         begin
  767.             ad := mp;
  768.             while ld > 0 do
  769.                 begin
  770.                     ad := store^[ad + 1].vm;
  771.                     ld := ld - 1
  772.                 end;
  773.             base := ad
  774.         end; (*base*)
  775.  
  776.         procedure compare;
  777. (*comparing is only correct if result by comparing integers will be*)
  778.         begin
  779.             i1 := store^[sp].va;
  780.             i2 := store^[sp + 1].va;
  781.             i := 0;
  782.             b := true;
  783.             while b and (i <> q) do
  784.                 if store^[i1 + i].vi = store^[i2 + i].vi then
  785.                     i := i + 1
  786.                 else
  787.                     b := false
  788.         end; (*compare*)
  789.  
  790.  
  791.         var
  792.             prrOpen: Boolean;
  793.  
  794.         procedure CheckPrr; {Fix to avoid a prr file if we don't need it!}
  795.             var
  796.                 newFile: Str255;
  797.         begin
  798.             if prrOpen then
  799.                 exit(CheckPrr);
  800. {            newFile := 'p4.err';}
  801. {            newFile := GetOutFile('Output file?', '');    Equivalent to NewFileName!}
  802.             newFile := NewFileName('Output file?');
  803.             rewrite(prr, newFile);
  804.         end;
  805.  
  806.  
  807.         procedure callsp;
  808.             var
  809.                 line: boolean;
  810.                 adptr, adelnt: address;
  811.                 i: integer;
  812.  
  813.             procedure readi (var f: text);
  814.                 var
  815.                     ad: address;
  816.             begin
  817.                 ad := store^[sp - 1].va;
  818.                 if @f = @input then
  819.                     begin
  820.                         store^[ad].vi := ConsoleReadInt;
  821.                         store^[store^[sp].va].vc := ConsolePeekChar;
  822.                     end
  823.                 else
  824.                     begin
  825.                         read(f, store^[ad].vi);
  826.                         store^[store^[sp].va].vc := f^;
  827.                     end;
  828.                 sp := sp - 2
  829.             end;(*readi*)
  830.  
  831.             procedure readr (var f: text);
  832.                 var
  833.                     ad: address;
  834.             begin
  835.                 ad := store^[sp - 1].va;
  836.                 if @f = @input then
  837.                     begin
  838.                         store^[ad].vr := ConsoleReadReal;
  839.                         store^[store^[sp].va].vc := ConsolePeekChar;
  840.                     end
  841.                 else
  842.                     begin
  843.                         read(f, store^[ad].vr);
  844.                         store^[store^[sp].va].vc := f^;
  845.                     end;
  846.                 sp := sp - 2
  847.             end;(*readr*)
  848.  
  849.             procedure readc (var f: text);
  850.                 var
  851.                     c: char;
  852.                     ad: address;
  853.             begin
  854.                 if @f = @input then
  855.                     c := ConsoleReadChar
  856.                 else
  857.                     read(f, c);
  858.                 ad := store^[sp - 1].va;
  859.                 store^[ad].vc := c;
  860.                 if @f = @input then
  861.                     begin
  862.                         store^[store^[sp].va].vc := ConsolePeekChar;            {???}
  863.                         store^[store^[sp].va].vi := ord(store^[store^[sp].va].vc);
  864.                     end
  865.                 else
  866.                     begin
  867.                         store^[store^[sp].va].vc := f^;
  868.                         store^[store^[sp].va].vi := ord(f^);
  869.                     end;
  870.                 sp := sp - 2
  871.             end;(*readc*)
  872.  
  873.             procedure writestr (var f: text);
  874.                 var
  875.                     i, j, k: integer;
  876.                     ad: address;
  877.             begin
  878.                 ad := store^[sp - 3].va;
  879.                 k := store^[sp - 2].vi;
  880.                 j := store^[sp - 1].vi;
  881.      (* j and k are numbers of characters *)
  882.                 if k > j then
  883.                     for i := 1 to k - j do
  884.                         if @f = @output then
  885.                             ConsoleWrite(' ')
  886.                         else
  887.                             write(f, ' ')
  888.                 else
  889.                     j := k;
  890.                 for i := 0 to j - 1 do
  891.                     if @f = @output then
  892.                         ConsoleWrite(store^[ad + i].vc)
  893.                     else
  894.                         write(f, store^[ad + i].vc);
  895.                 sp := sp - 4
  896.             end;(*writestr*)
  897.  
  898.             procedure getfile (var f: text);
  899.                 var
  900.                     ad: address;
  901.             begin
  902.                 ad := store^[sp].va;
  903.                 if @f = @input then
  904.                     store^[ad].vc := ConsoleReadChar
  905.                 else
  906.                     begin
  907.                         get(f);
  908.                         store^[ad].vc := f^;
  909.                     end;
  910.                 sp := sp - 1
  911.             end;(*getfile*)
  912.  
  913.             procedure putfile (var f: text);
  914.                 var
  915.                     ad: address;
  916.             begin
  917.                 ad := store^[sp].va;
  918.                 if @f = @output then
  919.                     ConsoleWrite(store^[ad].vc)
  920.                 else
  921.                     begin
  922.                         f^ := store^[ad].vc;
  923.                         put(f);
  924.                     end;
  925.                 sp := sp - 1;
  926.             end;(*putfile*)
  927.  
  928.         begin (*callsp*)
  929.             case q of
  930. 0 (*get*)
  931.                 : 
  932.                     case store^[sp].va of
  933.                         5: 
  934.                             ConsoleGet;                {getfile(input)}
  935.                         6: 
  936.                             errori(' get on output file      ');
  937.                         7: 
  938.                             getfile(prd);
  939.                         8: 
  940.                             errori(' get on prr file     ')
  941.                     end;
  942. 1 (*put*)
  943.                 : 
  944.                     case store^[sp].va of
  945.                         5: 
  946.                             errori(' put on read file    ');
  947.                         6: 
  948.                             ;
  949. {putfile(output)                VAD skall skrivas var då??? Behövs en output^???}
  950.                         7: 
  951.                             errori(' put on prd file     ');
  952.                         8: 
  953.                             begin
  954.                                 CheckPrr; {Fix to avoid a prr file if we don't need it!}
  955.                                 putfile(prr)
  956.                             end;
  957.                     end;
  958. 2 (*rst*)
  959.                 : 
  960.                     begin
  961.             (*for testphase*)
  962.                         np := store^[sp].va;
  963.                         sp := sp - 1
  964.                     end;
  965. 3 (*rln*)
  966.                 : 
  967.                     begin
  968.                         case store^[sp].va of
  969.                             5: 
  970.                                 begin
  971.                                     store^[inputadr].vc := ConsoleReadChar;
  972. {readln(input);store ^ [ inputadr ] . vc := input ^}
  973.                                 end;
  974.                             6: 
  975.                                 errori(' readln on output file   ');
  976.                             7: 
  977.                                 begin
  978.                                     store^[inputadr].vc := ConsoleReadChar;
  979. {readln(input);store^[inputadr].vc := input^}
  980.                                 end;
  981.                             8: 
  982.                                 errori(' readln on prr file      ')
  983.                         end;
  984.                         sp := sp - 1
  985.                     end;
  986. 4 (*new*)
  987.                 : 
  988.                     begin
  989.                         ad := np - store^[sp].va;
  990.               (*top of stack gives the length in units of storage *)
  991.                         if ad <= ep then
  992.                             errori(' store overflow      ');
  993.                         np := ad;
  994.                         ad := store^[sp - 1].va;
  995.                         store^[ad].va := np;
  996.                         sp := sp - 2
  997.                     end;
  998. 5 (*wln*)
  999.                 : 
  1000.                     begin
  1001.                         case store^[sp].va of
  1002.                             5: 
  1003.                                 errori(' writeln on input file   ');
  1004.                             6: 
  1005.                                 ConsoleNewLine;                {writeln(output);}
  1006.                             7: 
  1007.                                 errori(' writeln on prd file     ');
  1008.                             8: 
  1009.                                 begin
  1010.                                     CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1011.                                     writeln(prr)
  1012.                                 end;
  1013.                         end;
  1014.                         sp := sp - 1
  1015.                     end;
  1016. 6 (*wrs*)
  1017.                 : 
  1018.                     case store^[sp].va of
  1019.                         5: 
  1020.                             errori(' write on input file     ');
  1021.                         6: 
  1022.                             writestr(output);
  1023.                         7: 
  1024.                             errori(' write on prd file       ');
  1025.                         8: 
  1026.                             begin
  1027.                                 CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1028.                                 writestr(prr)
  1029.                             end;
  1030.                     end;
  1031. 7 (*eln*)
  1032.                 : 
  1033.                     begin
  1034.                         case store^[sp].va of
  1035.                             5: 
  1036.                                 line := eoln(input);
  1037.                             6: 
  1038.                                 errori(' eoln output file    ');
  1039.                             7: 
  1040.                                 line := eoln(prd);
  1041.                             8: 
  1042.                                 errori(' eoln on prr file    ')
  1043.                         end;
  1044.                         store^[sp].vb := line
  1045.                     end;
  1046. 8 (*wri*)
  1047.                 : 
  1048.                     begin
  1049.                         case store^[sp].va of
  1050.                             5: 
  1051.                                 errori(' write on input file     ');
  1052.                             6: 
  1053.                                 ConsoleWrite(StringOf(store^[sp - 2].vi : store^[sp - 1].vi));
  1054.                             7: 
  1055.                                 errori(' write on prd file       ');
  1056.                             8: 
  1057.                                 begin
  1058.                                     CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1059.                                     write(prr, store^[sp - 2].vi : store^[sp - 1].vi)
  1060.                                 end;
  1061.                         end;
  1062.                         sp := sp - 3
  1063.                     end;
  1064. 9 (*wrr*)
  1065.                 : 
  1066.                     begin
  1067.                         case store^[sp].va of
  1068.                             5: 
  1069.                                 errori(' write on input file     ');
  1070.                             6: 
  1071.                                 ConsoleWrite(StringOf(store^[sp - 2].vr : store^[sp - 1].vi));        {write(output,}
  1072.                             7: 
  1073.                                 errori(' write on prd file       ');
  1074.                             8: 
  1075.                                 begin
  1076.                                     CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1077.                                     write(prr, store^[sp - 2].vr : store^[sp - 1].vi)
  1078.                                 end;
  1079.                         end;
  1080.                         sp := sp - 3
  1081.                     end;
  1082. 10(*wrc*)
  1083.                 : 
  1084.                     begin
  1085.                         case store^[sp].va of
  1086.                             5: 
  1087.                                 errori(' write on input file     ');
  1088.                             6: 
  1089.                                 ConsoleWrite(StringOf(store^[sp - 2].vc : store^[sp - 1].vi));            {write(output,}
  1090.                             7: 
  1091.                                 errori(' write on prd file       ');
  1092.                             8: 
  1093.                                 begin
  1094.                                     CheckPrr; {Fix to avoid a prr file if we don't need it!}
  1095.                                     write(prr, chr(store^[sp - 2].vi) : store^[sp - 1].vi);
  1096.                                 end;
  1097.                         end;
  1098.                         sp := sp - 3
  1099.                     end;
  1100. 11(*rdi*)
  1101.                 : 
  1102.                     case store^[sp].va of
  1103.                         5: 
  1104.                             readi(input);
  1105.                         6: 
  1106.                             errori(' read on output file     ');
  1107.                         7: 
  1108.                             readi(prd);
  1109.                         8: 
  1110.                             errori(' read on prr file    ')
  1111.                     end;
  1112. 12(*rdr*)
  1113.                 : 
  1114.                     case store^[sp].va of
  1115.                         5: 
  1116.                             readr(input);
  1117.                         6: 
  1118.                             errori(' read on output file     ');
  1119.                         7: 
  1120.                             readr(prd);
  1121.                         8: 
  1122.                             errori(' read on prr file    ')
  1123.                     end;
  1124. 13(*rdc*)
  1125.                 : 
  1126.                     case store^[sp].va of
  1127.                         5: 
  1128.                             readc(input);
  1129.                         6: 
  1130.                             errori(' read on output file     ');
  1131.                         7: 
  1132.                             readc(prd);
  1133.                         8: 
  1134.                             errori(' read on prr file    ')
  1135.                     end;
  1136. 14(*sin*)
  1137.                 : 
  1138.                     store^[sp].vr := sin(store^[sp].vr);
  1139. 15(*cos*)
  1140.                 : 
  1141.                     store^[sp].vr := cos(store^[sp].vr);
  1142. 16(*exp*)
  1143.                 : 
  1144.                     store^[sp].vr := exp(store^[sp].vr);
  1145. 17(*log*)
  1146.                 : 
  1147.                     store^[sp].vr := ln(store^[sp].vr);
  1148. 18(*sqt*)
  1149.                 : 
  1150.                     store^[sp].vr := sqrt(store^[sp].vr);
  1151. 19(*atn*)
  1152.                 : 
  1153.                     store^[sp].vr := arctan(store^[sp].vr);
  1154. 20(*sav*)
  1155.                 : 
  1156.                     begin
  1157.                         ad := store^[sp].va;
  1158.                         store^[ad].va := np;
  1159.                         sp := sp - 1
  1160.                     end;
  1161.             end;(*case q*)
  1162.         end;(*callsp*)
  1163.  
  1164.         function CommandPeriod: Boolean;
  1165.             var
  1166.                 km: KeyMap;
  1167.         begin
  1168.             CommandPeriod := false;
  1169.             GetKeys(km);
  1170.             if km[47] and km[55] then
  1171.                 CommandPeriod := true;
  1172.         end; {CommandPeriod}
  1173.  
  1174.         function oldGetInFile: Str255;
  1175.             var
  1176.                 message, count: Integer;
  1177. {                theAppFile: AppFile;}
  1178.         begin
  1179. {AppFiles handling is obsolete.}
  1180. (*            CountAppFiles(message, count);}
  1181. {            if count > 0 then}
  1182. {                begin}
  1183. {                    GetAppFiles(1, theAppFile);}
  1184. {                    if SetVol(nil, theAppFile.vRefNum) <> noErr then}
  1185. {                        ; {We ignore errors for now}
  1186. {GetInFile := theAppFile.fname;}
  1187. {end}
  1188. {else}
  1189. {*)
  1190.             begin
  1191.                 oldGetInFile := OldFileName('');
  1192.             end;
  1193.         end; {GetInFile}
  1194.  
  1195. {For Stdfile-dialogs:}
  1196.         var
  1197. {oldFile: Str255; - numera argument!}
  1198.             theTextRect: Rect;
  1199.  
  1200.  
  1201.     begin (* main *)
  1202. {theTextRect := screenBits.bounds;}
  1203. {theTextRect.top := theTextRect.top + 40; {For menu bar and window top}
  1204. {InsetRect(theTextRect, 10, 10);}
  1205. {SetRect(theTextRect, 40, 40, 300, 300);}
  1206. {SetTextRect(theTextRect);}
  1207. {ShowText;}
  1208. {WriteMessageLine('Welcome to the P4Mac p-code interpreter!');}
  1209. {WriteMessageLine('This program is based on the Public Domain compiler P4.');}
  1210. {WriteMessageLine('Quick port for the Mac by Ingemar Ragnemalm - and don''t ask me why.');}
  1211. {WriteMessageLine('•••');}
  1212.  
  1213. {Fix for Think Pascal's stupid 32k limit:}
  1214.         if code = nil then
  1215.             code := codePtr(NewPtr(sizeof(codeType)));
  1216.         if code = nil then
  1217.             begin
  1218.                 SysBeep(1);
  1219.                 WriteMessageLine(StringOf('Out of memory trying to allocate ', sizeof(codeType) : 1, ' bytes for "code".'));
  1220.                 Exit(RunInterpreter);
  1221.             end;
  1222.         if store = nil then
  1223.             store := storePtr(NewPtr(sizeof(storeType)));
  1224.         if store = nil then
  1225.             begin
  1226.                 SysBeep(1);
  1227.                 WriteMessageLine(StringOf('Out of memory trying to allocate ', sizeof(storeType) : 1, ' bytes for "store".'));
  1228.                 Exit(RunInterpreter);
  1229.             end;
  1230.  
  1231. {close(prd); {Behövs det?}
  1232.  
  1233.         if oldFile = '' then
  1234.             oldFile := GetInFile;
  1235.         reset(prd, oldFile);
  1236.  
  1237. {newFile := NewFileName('Output file?');}
  1238.  
  1239. {Borde inte rewrite'a prr förrän vi ser att det krävs nåt ut, väl?}
  1240. {rewrite(prr, newFile); {Var förr rewrite(prr)!!!}
  1241.         prrOpen := false; {Not open yet!}
  1242.  
  1243.         load; (* assembles and stores code *)
  1244.   (* writeln(output); for testing *)
  1245.         pc := 0;
  1246.         sp := -1;
  1247.         mp := 0;
  1248.         np := maxstk + 1;
  1249.         ep := 5;
  1250. {store^[inputadr].vc := input^;}
  1251. {store^[prdadr].vc := prd^; {???}
  1252.         interpreting := true;
  1253.         aborted := false;
  1254.         ConsoleResetRead;    {The read buffer must be cleared from the last run}
  1255.  
  1256.         while interpreting and not aborted do
  1257.             begin
  1258.  
  1259.                 if CommandPeriod then
  1260.                     begin
  1261.                         ConsoleNewLine;
  1262.                         ConsoleWriteln('•••Execution terminated by user•••');
  1263.                         Exit(RunInterpreter);
  1264.                     end;
  1265.  
  1266.     (*fetch*)
  1267.                 with code^[pc div 2] do
  1268.                     if odd(pc) then
  1269.                         begin
  1270.                             op := op2;
  1271.                             p := p2;
  1272.                             q := q2
  1273.                         end
  1274.                     else
  1275.                         begin
  1276.                             op := op1;
  1277.                             p := p1;
  1278.                             q := q1
  1279.                         end;
  1280.                 pc := pc + 1;
  1281.  
  1282.     (*execute*)
  1283.                 case op of
  1284.  
  1285.                     105, 106, 107, 108, 109, 0 (*lod*)
  1286.                     : 
  1287.                         begin
  1288.                             ad := base(p) + q;
  1289.                             sp := sp + 1;
  1290.                             store^[sp] := store^[ad]
  1291.                         end;
  1292.  
  1293.                     65, 66, 67, 68, 69, 1 (*ldo*)
  1294.                     : 
  1295.                         begin
  1296.                             sp := sp + 1;
  1297.                             store^[sp] := store^[q]
  1298.                         end;
  1299.  
  1300.                     70, 71, 72, 73, 74, 2 (*str*)
  1301.                     : 
  1302.                         begin
  1303.                             store^[base(p) + q] := store^[sp];
  1304.                             sp := sp - 1
  1305.                         end;
  1306.  
  1307.                     75, 76, 77, 78, 79, 3 (*sro*)
  1308.                     : 
  1309.                         begin
  1310.                             store^[q] := store^[sp];
  1311.                             sp := sp - 1
  1312.                         end;
  1313.  
  1314. 4 (*lda*)
  1315.                     : 
  1316.                         begin
  1317.                             sp := sp + 1;
  1318.                             store^[sp].va := base(p) + q
  1319.                         end;
  1320.  
  1321. 5 (*lao*)
  1322.                     : 
  1323.                         begin
  1324.                             sp := sp + 1;
  1325.                             store^[sp].va := q
  1326.                         end;
  1327.  
  1328.                     80, 81, 82, 83, 84, 6 (*sto*)
  1329.                     : 
  1330.                         begin
  1331.                             store^[store^[sp - 1].va] := store^[sp];
  1332.                             sp := sp - 2;
  1333.                         end;
  1334.  
  1335. 7 (*ldc*)
  1336.                     : 
  1337.                         begin
  1338.                             sp := sp + 1;
  1339.                             if p = 1 then
  1340.                                 begin
  1341.                                     store^[sp].vi := q;
  1342.                                 end
  1343.                             else if p = 6 then
  1344.                                 store^[sp].vc := chr(q)
  1345.                             else if p = 3 then
  1346.                                 store^[sp].vb := q = 1
  1347.                             else (* load nil *)
  1348.                                 store^[sp].va := maxstr
  1349.                         end;
  1350.  
  1351. 8 (*lci*)
  1352.                     : 
  1353.                         begin
  1354.                             sp := sp + 1;
  1355.                             store^[sp] := store^[q]
  1356.                         end;
  1357.  
  1358.                     85, 86, 87, 88, 89, 9 (*ind*)
  1359.                     : 
  1360.                         begin
  1361.                             ad := store^[sp].va + q;
  1362.               (* q is a number of storage units *)
  1363.                             store^[sp] := store^[ad]
  1364.                         end;
  1365.  
  1366.                     90, 91, 92, 93, 94, 10 (*inc*)
  1367.                     : 
  1368.                         store^[sp].vi := store^[sp].vi + q;
  1369.  
  1370. 11 (*mst*)
  1371.                     : 
  1372.                         begin (*p=level of calling procedure minus level of called}
  1373. {                  procedure + 1;  set dl and sl, increment sp*)
  1374.                (* then length of this element is}
  1375. {              max(intsize,realsize,boolsize,charsize,ptrsize *)
  1376.                             store^[sp + 2].vm := base(p);
  1377.                (* the length of this element is ptrsize *)
  1378.                             store^[sp + 3].vm := mp;
  1379.                (* idem *)
  1380.                             store^[sp + 4].vm := ep;
  1381.                (* idem *)
  1382.                             sp := sp + 5
  1383.                         end;
  1384.  
  1385. 12 (*cup*)
  1386.                     : 
  1387.                         begin (*p=no of locations for parameters, q=entry point*)
  1388.                             mp := sp - (p + 4);
  1389.                             store^[mp + 4].vm := pc;
  1390.                             pc := q
  1391.                         end;
  1392.  
  1393. 13 (*ent*)
  1394.                     : 
  1395.                         if p = 1 then
  1396.                             begin
  1397.                                 sp := mp + q; (*q = length of dataseg*)
  1398.                                 if sp > np then
  1399.                                     errori(' store overflow      ');
  1400.                             end
  1401.                         else
  1402.                             begin
  1403.                                 ep := sp + q;
  1404.                                 if ep > np then
  1405.                                     errori(' store overflow      ');
  1406.                             end;
  1407.             (*q = max space required on stack*)
  1408.  
  1409. 14 (*ret*)
  1410.                     : 
  1411.                         begin
  1412.                             case p of
  1413.                                 0: 
  1414.                                     sp := mp - 1;
  1415.                                 1, 2, 3, 4, 5: 
  1416.                                     sp := mp
  1417.                             end;
  1418.                             pc := store^[mp + 4].vm;
  1419.                             ep := store^[mp + 3].vm;
  1420.                             mp := store^[mp + 2].vm;
  1421.                         end;
  1422.  
  1423. 15 (*csp*)
  1424.                     : 
  1425.                         callsp;
  1426.  
  1427. 16 (*ixa*)
  1428.                     : 
  1429.                         begin
  1430.                             i := store^[sp].vi;
  1431.                             sp := sp - 1;
  1432.                             store^[sp].va := q * i + store^[sp].va;
  1433.                         end;
  1434.  
  1435. 17 (*equ*)
  1436.                     : 
  1437.                         begin
  1438.                             sp := sp - 1;
  1439.                             case p of
  1440.                                 1: 
  1441.                                     store^[sp].vb := store^[sp].vi = store^[sp + 1].vi;
  1442.                                 0: 
  1443.                                     store^[sp].vb := store^[sp].va = store^[sp + 1].va;
  1444.                                 6: 
  1445.                                     store^[sp].vb := store^[sp].vc = store^[sp + 1].vc;
  1446.                                 2: 
  1447.                                     store^[sp].vb := store^[sp].vr = store^[sp + 1].vr;
  1448.                                 3: 
  1449.                                     store^[sp].vb := store^[sp].vb = store^[sp + 1].vb;
  1450.                                 4: 
  1451.                                     store^[sp].vb := store^[sp].vs = store^[sp + 1].vs;
  1452.                                 5: 
  1453.                                     begin
  1454.                                         compare;
  1455.                                         store^[sp].vb := b;
  1456.                                     end;
  1457.                             end; (*case p*)
  1458.                         end;
  1459.  
  1460. 18 (*neq*)
  1461.                     : 
  1462.                         begin
  1463.                             sp := sp - 1;
  1464.                             case p of
  1465.                                 0: 
  1466.                                     store^[sp].vb := store^[sp].va <> store^[sp + 1].va;
  1467.                                 1: 
  1468.                                     store^[sp].vb := store^[sp].vi <> store^[sp + 1].vi;
  1469.                                 6: 
  1470.                                     store^[sp].vb := store^[sp].vc <> store^[sp + 1].vc;
  1471.                                 2: 
  1472.                                     store^[sp].vb := store^[sp].vr <> store^[sp + 1].vr;
  1473.                                 3: 
  1474.                                     store^[sp].vb := store^[sp].vb <> store^[sp + 1].vb;
  1475.                                 4: 
  1476.                                     store^[sp].vb := store^[sp].vs <> store^[sp + 1].vs;
  1477.                                 5: 
  1478.                                     begin
  1479.                                         compare;
  1480.                                         store^[sp].vb := not b;
  1481.                                     end
  1482.                             end; (*case p*)
  1483.                         end;
  1484.  
  1485. 19 (*geq*)
  1486.                     : 
  1487.                         begin
  1488.                             sp := sp - 1;
  1489.                             case p of
  1490.                                 0: 
  1491.                                     errori(' <,<=,>,>= for address   ');
  1492.                                 1: 
  1493.                                     store^[sp].vb := store^[sp].vi >= store^[sp + 1].vi;
  1494.                                 6: 
  1495.                                     store^[sp].vb := store^[sp].vc >= store^[sp + 1].vc;
  1496.                                 2: 
  1497.                                     store^[sp].vb := store^[sp].vr >= store^[sp + 1].vr;
  1498.                                 3: 
  1499.                                     store^[sp].vb := store^[sp].vb >= store^[sp + 1].vb;
  1500.                                 4: 
  1501.                                     store^[sp].vb := store^[sp].vs >= store^[sp + 1].vs;
  1502.                                 5: 
  1503.                                     begin
  1504.                                         compare;
  1505.                                         store^[sp].vb := b or (store^[i1 + i].vi >= store^[i2 + i].vi)
  1506.                                     end
  1507.                             end; (*case p*)
  1508.                         end;
  1509.  
  1510. 20 (*grt*)
  1511.                     : 
  1512.                         begin
  1513.                             sp := sp - 1;
  1514.                             case p of
  1515.                                 0: 
  1516.                                     errori(' <,<=,>,>= for address   ');
  1517.                                 1: 
  1518.                                     store^[sp].vb := store^[sp].vi > store^[sp + 1].vi;
  1519.                                 6: 
  1520.                                     store^[sp].vb := store^[sp].vc > store^[sp + 1].vc;
  1521.                                 2: 
  1522.                                     store^[sp].vb := store^[sp].vr > store^[sp + 1].vr;
  1523.                                 3: 
  1524.                                     store^[sp].vb := store^[sp].vb > store^[sp + 1].vb;
  1525.                                 4: 
  1526.                                     errori(' set inclusion       ');
  1527.                                 5: 
  1528.                                     begin
  1529.                                         compare;
  1530.                                         store^[sp].vb := not b and (store^[i1 + i].vi > store^[i2 + i].vi)
  1531.                                     end
  1532.                             end; (*case p*)
  1533.                         end;
  1534.  
  1535. 21 (*leq*)
  1536.                     : 
  1537.                         begin
  1538.                             sp := sp - 1;
  1539.                             case p of
  1540.                                 0: 
  1541.                                     errori(' <,<=,>,>= for address   ');
  1542.                                 1: 
  1543.                                     store^[sp].vb := store^[sp].vi <= store^[sp + 1].vi;
  1544.                                 6: 
  1545.                                     store^[sp].vb := store^[sp].vc <= store^[sp + 1].vc;
  1546.                                 2: 
  1547.                                     store^[sp].vb := store^[sp].vr <= store^[sp + 1].vr;
  1548.                                 3: 
  1549.                                     store^[sp].vb := store^[sp].vb <= store^[sp + 1].vb;
  1550.                                 4: 
  1551.                                     store^[sp].vb := store^[sp].vs <= store^[sp + 1].vs;
  1552.                                 5: 
  1553.                                     begin
  1554.                                         compare;
  1555.                                         store^[sp].vb := b or (store^[i1 + i].vi <= store^[i2 + i].vi)
  1556.                                     end;
  1557.                             end; (*case p*)
  1558.                         end;
  1559.  
  1560. 22 (*les*)
  1561.                     : 
  1562.                         begin
  1563.                             sp := sp - 1;
  1564.                             case p of
  1565.                                 0: 
  1566.                                     errori(' <,<=,>,>= for address   ');
  1567.                                 1: 
  1568.                                     store^[sp].vb := store^[sp].vi < store^[sp + 1].vi;
  1569.                                 6: 
  1570.                                     store^[sp].vb := store^[sp].vc < store^[sp + 1].vc;
  1571.                                 2: 
  1572.                                     store^[sp].vb := store^[sp].vr < store^[sp + 1].vr;
  1573.                                 3: 
  1574.                                     store^[sp].vb := store^[sp].vb < store^[sp + 1].vb;
  1575.                                 5: 
  1576.                                     begin
  1577.                                         compare;
  1578.                                         store^[sp].vb := not b and (store^[i1 + i].vi < store^[i2 + i].vi)
  1579.                                     end
  1580.                             end; (*case p*)
  1581.                         end;
  1582.  
  1583. 23 (*ujp*)
  1584.                     : 
  1585.                         pc := q;
  1586.  
  1587. 24 (*fjp*)
  1588.                     : 
  1589.                         begin
  1590.                             if not store^[sp].vb then
  1591.                                 pc := q;
  1592.                             sp := sp - 1
  1593.                         end;
  1594.  
  1595. 25 (*xjp*)
  1596.                     : 
  1597.                         begin
  1598.                             pc := store^[sp].vi + q;
  1599.                             sp := sp - 1
  1600.                         end;
  1601.  
  1602. 95 (*chka*)
  1603.                     : 
  1604.                         if (store^[sp].va < np) or (store^[sp].va > (maxstr - q)) then
  1605.                             errori(' bad pointer value       ');
  1606.  
  1607.                     96, 97, 98, 99, 26 (*chk*)
  1608.                     : 
  1609.                         if (store^[sp].vi < store^[q - 1].vi) or (store^[sp].vi > store^[q].vi) then
  1610.                             errori(' value out of range      ');
  1611.  
  1612. 27 (*eof*)
  1613.                     : 
  1614.                         begin
  1615.                             i := store^[sp].vi;
  1616.                             if i = inputadr then
  1617.                                 begin
  1618.                                     store^[sp].vb := eof(input);
  1619.                                 end
  1620.                             else
  1621.                                 errori(' code in error       ')
  1622.                         end;
  1623.  
  1624. 28 (*adi*)
  1625.                     : 
  1626.                         begin
  1627.                             sp := sp - 1;
  1628.                             store^[sp].vi := store^[sp].vi + store^[sp + 1].vi
  1629.                         end;
  1630.  
  1631. 29 (*adr*)
  1632.                     : 
  1633.                         begin
  1634.                             sp := sp - 1;
  1635.                             store^[sp].vr := store^[sp].vr + store^[sp + 1].vr
  1636.                         end;
  1637.  
  1638. 30 (*sbi*)
  1639.                     : 
  1640.                         begin
  1641.                             sp := sp - 1;
  1642.                             store^[sp].vi := store^[sp].vi - store^[sp + 1].vi
  1643.                         end;
  1644.  
  1645. 31 (*sbr*)
  1646.                     : 
  1647.                         begin
  1648.                             sp := sp - 1;
  1649.                             store^[sp].vr := store^[sp].vr - store^[sp + 1].vr
  1650.                         end;
  1651.  
  1652. 32 (*sgs*)
  1653.                     : 
  1654.                         store^[sp].vs := [store^[sp].vi];
  1655.  
  1656. 33 (*flt*)
  1657.                     : 
  1658.                         store^[sp].vr := store^[sp].vi;
  1659.  
  1660. 34 (*flo*)
  1661.                     : 
  1662.                         store^[sp - 1].vr := store^[sp - 1].vi;
  1663.  
  1664. 35 (*trc*)
  1665.                     : 
  1666.                         store^[sp].vi := trunc(store^[sp].vr);
  1667.  
  1668. 36 (*ngi*)
  1669.                     : 
  1670.                         store^[sp].vi := -store^[sp].vi;
  1671.  
  1672. 37 (*ngr*)
  1673.                     : 
  1674.                         store^[sp].vr := -store^[sp].vr;
  1675.  
  1676. 38 (*sqi*)
  1677.                     : 
  1678.                         store^[sp].vi := sqr(store^[sp].vi);
  1679.  
  1680. 39 (*sqr*)
  1681.                     : 
  1682.                         store^[sp].vr := sqr(store^[sp].vr);
  1683.  
  1684. 40 (*abi*)
  1685.                     : 
  1686.                         store^[sp].vi := abs(store^[sp].vi);
  1687.  
  1688. 41 (*abr*)
  1689.                     : 
  1690.                         store^[sp].vr := abs(store^[sp].vr);
  1691.  
  1692. 42 (*not*)
  1693.                     : 
  1694.                         store^[sp].vb := not store^[sp].vb;
  1695.  
  1696. 43 (*and*)
  1697.                     : 
  1698.                         begin
  1699.                             sp := sp - 1;
  1700.                             store^[sp].vb := store^[sp].vb and store^[sp + 1].vb
  1701.                         end;
  1702.  
  1703. 44 (*ior*)
  1704.                     : 
  1705.                         begin
  1706.                             sp := sp - 1;
  1707.                             store^[sp].vb := store^[sp].vb or store^[sp + 1].vb
  1708.                         end;
  1709.  
  1710. 45 (*dif*)
  1711.                     : 
  1712.                         begin
  1713.                             sp := sp - 1;
  1714.                             store^[sp].vs := store^[sp].vs - store^[sp + 1].vs
  1715.                         end;
  1716.  
  1717. 46 (*int*)
  1718.                     : 
  1719.                         begin
  1720.                             sp := sp - 1;
  1721.                             store^[sp].vs := store^[sp].vs * store^[sp + 1].vs
  1722.                         end;
  1723.  
  1724. 47 (*uni*)
  1725.                     : 
  1726.                         begin
  1727.                             sp := sp - 1;
  1728.                             store^[sp].vs := store^[sp].vs + store^[sp + 1].vs
  1729.                         end;
  1730.  
  1731. 48 (*inn*)
  1732.                     : 
  1733.                         begin
  1734.                             sp := sp - 1;
  1735.                             i := store^[sp].vi;
  1736.                             store^[sp].vb := i in store^[sp + 1].vs;
  1737.                         end;
  1738.  
  1739. 49 (*mod*)
  1740.                     : 
  1741.                         begin
  1742.                             sp := sp - 1;
  1743.                             store^[sp].vi := store^[sp].vi mod store^[sp + 1].vi
  1744.                         end;
  1745.  
  1746. 50 (*odd*)
  1747.                     : 
  1748.                         store^[sp].vb := odd(store^[sp].vi);
  1749.  
  1750. 51 (*mpi*)
  1751.                     : 
  1752.                         begin
  1753.                             sp := sp - 1;
  1754.                             store^[sp].vi := store^[sp].vi * store^[sp + 1].vi
  1755.                         end;
  1756.  
  1757. 52 (*mpr*)
  1758.                     : 
  1759.                         begin
  1760.                             sp := sp - 1;
  1761.                             store^[sp].vr := store^[sp].vr * store^[sp + 1].vr
  1762.                         end;
  1763.  
  1764. 53 (*dvi*)
  1765.                     : 
  1766.                         begin
  1767.                             sp := sp - 1;
  1768.                             store^[sp].vi := store^[sp].vi div store^[sp + 1].vi
  1769.                         end;
  1770.  
  1771. 54 (*dvr*)
  1772.                     : 
  1773.                         begin
  1774.                             sp := sp - 1;
  1775.                             store^[sp].vr := store^[sp].vr / store^[sp + 1].vr
  1776.                         end;
  1777.  
  1778. 55 (*mov*)
  1779.                     : 
  1780.                         begin
  1781.                             i1 := store^[sp - 1].va;
  1782.                             i2 := store^[sp].va;
  1783.                             sp := sp - 2;
  1784.                             for i := 0 to q - 1 do
  1785.                                 store^[i1 + i] := store^[i2 + i]
  1786.                (* q is a number of storage units *)
  1787.                         end;
  1788.  
  1789. 56 (*lca*)
  1790.                     : 
  1791.                         begin
  1792.                             sp := sp + 1;
  1793.                             store^[sp].va := q;
  1794.                         end;
  1795.  
  1796.                     100, 101, 102, 103, 104, 57 (*dec*)
  1797.                     : 
  1798.                         store^[sp].vi := store^[sp].vi - q;
  1799.  
  1800. 58 (*stp*)
  1801.                     : 
  1802.                         interpreting := false;
  1803.  
  1804. 59 (*ord*)
  1805.                     : (*only used to change the tagfield*)
  1806.                         begin
  1807.                         end;
  1808.  
  1809. 60 (*chr*)
  1810.                     : 
  1811.                         begin
  1812.                         end;
  1813.  
  1814. 61 (*ujc*)
  1815.                     : 
  1816.                         errori(' case - error        ');
  1817.                 end
  1818.             end; (*while interpreting*)
  1819.  
  1820. 1:
  1821.         close(prd);
  1822.  
  1823. {Exit:}
  1824.         ConsoleNewLine;
  1825.         if aborted then
  1826.             ConsoleWriteln('•••Execution terminated by user•••')
  1827.         else
  1828.             ConsoleWriteln('•••');
  1829.  
  1830. {Writeln('Hit return to exit');}
  1831. {readln(oldFile); {read to anything}
  1832. {writeln('Click mouse to exit.');}
  1833. {while not Button do ;}
  1834.     end;
  1835.  
  1836. end.